#include "boost/multi_array.hpp"
#include <stdio.h>
#include <cassert>


int main () {
  // Create a 3D array that is 3 x 4 x 2
  
  // typedef of the array & index
  typedef boost::multi_array<double, 3> array_type;
  typedef array_type::index index;
  typedef array_type::size_type size_type;
  typedef array_type::index_gen my_idx_gen;
  
  // define range type
  typedef array_type::index_range my_idx_rng;
  
  // extents keyword to initialize size of the array
  array_type A(boost::extents[20][20][20]);
  array_type B(boost::extents[20][20][20]);

  // Assign values to the elements
  // access element one-by-one
  int values = 0;
  for(index i = 0; i != 10; ++i) 
    for(index j = 0; j != 10; ++j)
      for(index k = 0; k != 10; ++k)
      {
        A[i][j][k] = values++;
	printf("%.2f ", A[i][j][k]);
      }

  // Verify values
  int verify = 0;
  for(index i = 0; i != 10; ++i)
    for(index j = 0; j != 10; ++j)
      for(index k = 0; k != 10; ++k)
        assert(A[i][j][k] == verify++);

  // Range access
  my_idx_rng idx_rng, idx_rng1, idx_rng2;
  
  idx_rng  = my_idx_rng().start(0).finish(4).stride(2);
  idx_rng1 = my_idx_rng(0,4,2);
  idx_rng2 = my_idx_rng().start(0).stride(2).finish(4);
  
  my_idx_gen idx_gen;
  
  // error here assignment
  // cannot copy/assign matrix yet
  //B = A[ idx_gen[idx_rng][idx_rng1][idx_rng2] ];
    
  const size_type*  B_sz= B.shape();
  printf("B size is (%zu,%zx,%zd)",B_sz[0],B_sz[1],B_sz[2]);
  getchar();  
  
  return 0;
}
